import React, { useState, useRef } from "react";
import {
  Upload,
  Button,
  message,
  Row,
  Col,
  Card,
  Typography,
  Space,
  Divider,
} from "antd";
import { DownloadOutlined, InboxOutlined } from "@ant-design/icons";
import ReactCrop, {
  type Crop,
  centerCrop,
  makeAspectCrop,
  PixelCrop,
  PercentCrop,
} from "react-image-crop";
import "react-image-crop/dist/ReactCrop.css";
import type { RcFile, UploadFile, UploadProps } from "antd/es/upload/interface";
import ToolTitle from "@/components/ToolTitle";
import { imgToolsData } from "@/components/ToolsData";

const { Text } = Typography;
const { Dragger } = Upload;

interface ImgFormat {
  type: string;
  label: string;
}

const ImageCropping: React.FC = () => {
  const [fileList, setFileList] = useState<UploadFile[]>([]);
  const [originalImage, setOriginalImage] = useState<string>("");
  const [crop, setCrop] = useState<Crop>({
    unit: "%",
    x: 0,
    y: 0,
    width: 100,
    height: 100,
  });
  const [completedCrop, setCompletedCrop] = useState<PixelCrop | null>(null);
  const imgRef = useRef<HTMLImageElement>(null);

  // 支持的图片格式
  const supportedFormats: ImgFormat[] = [
    { type: "png", label: "PNG" },
    { type: "jpg", label: "JPG" },
    { type: "webp", label: "WEBP" },
  ];

  function onImageLoad(e: React.SyntheticEvent<HTMLImageElement>) {
    const { width, height } = e.currentTarget;

    // 计算初始裁剪区域，使用百分比单位
    const initialCrop: PercentCrop = makeAspectCrop(
      {
        unit: "%",
        width: 90,
      },
      16 / 9,
      width,
      height
    );

    // 居中裁剪区域
    const centeredCrop = centerCrop(initialCrop, width, height);
    setCrop(centeredCrop);
  }

  const handleUploadChange: UploadProps["onChange"] = ({
    fileList: newFileList,
  }) => {
    setFileList(newFileList);

    // 确保有文件并且已经上传完成
    if (newFileList.length > 0 && newFileList[0].originFileObj) {
      const file = newFileList[0].originFileObj as RcFile;
      const reader = new FileReader();
      reader.onload = () => {
        setOriginalImage(reader.result as string);
        setCompletedCrop(null); // 重置裁剪状态
      };
      reader.readAsDataURL(file);
    }
  };

  const beforeUpload = (file: RcFile) => {
    const isImage = /image\/(jpeg|jpg|png|gif|webp|svg|ico)/.test(file.type);
    if (!isImage) {
      message.error("只能上传图片文件!");
    }
    return isImage || Upload.LIST_IGNORE;
  };

  const handleDownload = (format: string) => {
    if (!originalImage || !completedCrop || !imgRef.current) {
      message.warning("请先上传并裁剪图片");
      return;
    }

    const image = imgRef.current;
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");

    if (!ctx) {
      message.error("无法创建canvas上下文");
      return;
    }

    // 获取原始图像尺寸比例
    const scaleX = image.naturalWidth / image.width;
    const scaleY = image.naturalHeight / image.height;

    // 设置canvas尺寸为裁剪区域大小（像素）
    canvas.width = completedCrop.width;
    canvas.height = completedCrop.height;

    // 绘制裁剪区域到canvas（completedCrop已是像素单位）
    ctx.drawImage(
      image,
      completedCrop.x * scaleX,
      completedCrop.y * scaleY,
      completedCrop.width * scaleX,
      completedCrop.height * scaleY,
      0,
      0,
      completedCrop.width,
      completedCrop.height
    );

    // 将canvas内容转为指定格式的图片
    const dataUrl = canvas.toDataURL(`image/${format}`);

    // 创建下载链接
    const link = document.createElement("a");
    link.download = `cropped-image.${format}`;
    link.href = dataUrl;
    link.click();

    message.success(`图片已保存为${format.toUpperCase()}格式`);
  };

  const uploadProps: UploadProps = {
    name: "file",
    multiple: false,
    fileList: fileList,
    beforeUpload: beforeUpload,
    onChange: handleUploadChange,
    showUploadList: false,
    customRequest: ({ onSuccess }) => {
      setTimeout(() => {
        onSuccess?.("ok");
      }, 0);
    },
  };

  return (
    <Card>
      <ToolTitle
        title={
          imgToolsData.find((item) => item.title === "图片裁剪")?.title || ""
        }
        description={
          imgToolsData.find((item) => item.title === "图片裁剪")?.description ||
          ""
        }
      />

      <Divider />

      <Row gutter={[24, 24]}>
        <Col xs={24} md={16}>
          <Card>
            {originalImage ? (
              <div style={{ textAlign: "center" }}>
                <ReactCrop
                  crop={crop}
                  onChange={(c) => setCrop(c)}
                  onComplete={(c) => setCompletedCrop(c)}
                  aspect={16 / 9}
                >
                  <img
                    ref={imgRef}
                    src={originalImage}
                    alt="裁剪区域"
                    style={{ maxWidth: "100%", maxHeight: "400px" }}
                    onLoad={onImageLoad}
                  />
                </ReactCrop>
                {completedCrop && (
                  <div style={{ marginTop: 16, color: "#52c41a" }}>
                    <Text strong>裁剪区域已选择，点击右侧按钮下载</Text>
                  </div>
                )}
              </div>
            ) : (
              <div
                style={{
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "center",
                  height: "300px",
                  background: "#f5f5f5",
                  borderRadius: "4px",
                }}
              >
                <Text type="secondary">请先上传图片</Text>
              </div>
            )}
          </Card>
        </Col>

        <Col xs={24} md={8}>
          <Card title="操作区">
            <Space direction="vertical" style={{ width: "100%" }}>
              <Dragger {...uploadProps}>
                <p className="ant-upload-drag-icon">
                  <InboxOutlined />
                </p>
                <p className="ant-upload-text">
                  拖拽图片文件到此处，或点击选择文件
                </p>
                <p className="ant-upload-hint">
                  支持文件格式: jpg, jpeg, png, gif, webp, svg, ico
                </p>
              </Dragger>

              <Divider>下载裁剪后的图片</Divider>

              <Space wrap>
                {supportedFormats.map((format) => (
                  <Button
                    key={format.type}
                    type="primary"
                    icon={<DownloadOutlined />}
                    onClick={() => handleDownload(format.type)}
                    disabled={!originalImage || !completedCrop}
                  >
                    我要下载 {format.label}
                  </Button>
                ))}
              </Space>
            </Space>
          </Card>
        </Col>
      </Row>
    </Card>
  );
};

export default ImageCropping;
